
console.log(a);
let a
// 为了模拟执行上下文栈的行为，让我们定义执行上下文栈是一个数组：
let ECStack = [];
// 试想当 JavaScript 开始要解释执行代码的时候，最先遇到的就是全局代码，所以初始化的时候首先就会向执行上下文栈压入一个全局执行上下文，我们用 globalContext 表示它，并且只有当整个应用程序结束的时候，ECStack 才会被清空，所以程序结束之前， ECStack 最底部永远有个 globalContext：
ECStack = [
  // globalContext
];

function first() {
  console.log('Inside first function');
  second();
  console.log('Again inside first function');
}

function second() {
  console.log('Inside second function');
  third()
}
function third(){
  console.log("third function");
}

first();
console.log('Inside Global Execution Context');

// 当执行一个函数的时候，就会创建一个执行上下文，并且压入执行上下文栈，当函数执行完毕的时候，就会将函数的执行上下文从栈中弹出。知道了这样的工作原理，让我们来看看如何处理上面这段代码：
/* 
// 伪代码
// first()
ECStack.push(<first> functionContext);

// first中竟然调用了second，还要创建second的执行上下文
ECStack.push(<second> functionContext);

// 擦，second还调用了third！
ECStack.push(<third> functionContext);

//third执行完毕
ECStack.pop();

// second执行完毕
ECStack.pop();

// first执行完毕
ECStack.pop();
// javascript接着执行下面的代码，但是ECStack底层永远有个globalContext
*/
/* 
                  Inside first function
js执行上下文.js:15 Inside second function
js执行上下文.js:19 third function
js执行上下文.js:11 Again inside first function
js执行上下文.js:23 Inside Global Execution Context
*/
// 链接：https://juejin.im/post/5ba32171f265da0ab719a6d7